<template>
  <n-modal
    v-model:show="getProps.modalData.show"
    class="custom-card"
    preset="card"
    :style="{ width: '800px' }"
    title="选择类目"
    :bordered="false"
    :segmented="{
      content: true,
      footer: true
    }"
  >
    <div class="container">
      <div v-if="latestUsedList[0]" class="latest-used-box">
        <div class="flex top">
          <n-text :depth="3" class="flex-none" style="margin: 5px 10px 0 0">最近使用</n-text>
          <div class="category-list">
            <n-space>
              <n-tag
                v-for="(item, index) in latestUsedList"
                :key="index"
                class="category-tag"
                :bordered="false"
                @click="handleClickTag(item)"
              >
                {{ item.categoryName1 }}＞{{ item.categoryName2 }}＞{{ item.categoryName3 }}
              </n-tag>
            </n-space>
          </div>
        </div>
      </div>

      <div class="content-box">
        <div class="search">
          <n-select
            v-model:value="selectedValue"
            filterable
            placeholder="请输入类目或类目关键词"
            :options="searchList"
            :loading="loading"
            clearable
            remote
            :render-label="renderLabel"
            @search="handleSearch"
            @update:value="handleUpdateSelectedValue"
          />
        </div>
        <div class="category-box">
          <CategoryItem v-model:value="selectedCategory1" :level="1" @update:value="handleUpdateCategory1" />
          <CategoryItem
            v-model:value="selectedCategory2"
            :level="2"
            :parent-id="selectedCategory1.categoryId"
            @update:value="handleUpdateCategory2"
          />
          <CategoryItem
            v-model:value="selectedCategory3"
            :level="3"
            :parent-id="selectedCategory2.categoryId"
            @update:value="handleUpdateCategory3"
          />
        </div>
      </div>

      <div v-if="displaySelectedCategory" class="selected-box flex">
        <n-text :depth="3" class="flex-none" style="margin-right: 10px">已选类目</n-text>
        <div>
          {{ displaySelectedCategory }}
        </div>
      </div>
    </div>

    <template #footer>
      <n-space justify="end">
        <n-button @click="handleClose">取消</n-button>
        <n-button type="primary" :disabled="!selectedCategory3.categoryId" @click="handleConfirm">确定</n-button>
      </n-space>
    </template>
  </n-modal>
</template>

<script setup lang="ts">
  import { NModal, NSpace, NButton, NText, NTag, NSelect } from 'naive-ui'
  import { useStore } from '@/store'
  import { reactive, ref, onMounted, h, computed } from 'vue'
  import { ProductCategoryListModel } from '@/api/model/productModel'
  import CategoryItem from './category-item.vue'

  const store = useStore()
  const props = defineProps({
    modalData: {
      type: Object,
      default: () => ({})
    },

    defaultValue: {
      type: Array,
      default: () => []
    }
  })

  interface ISelectedCategory {
    categoryName: string
    categoryId: number | null
  }

  const emits = defineEmits(['success'])
  const getProps = reactive(props)

  const latestUsedList = ref([])
  const selectedValue = ref(null)
  const searchValue = ref('')
  const loading = ref(false)
  const searchList = ref([])
  const selectedCategory1 = ref<ISelectedCategory>({
    categoryName: '',
    categoryId: null
  })
  const selectedCategory2 = ref<ISelectedCategory>({
    categoryName: '',
    categoryId: null
  })
  const selectedCategory3 = ref<ISelectedCategory>({
    categoryName: '',
    categoryId: null
  })
  const displaySelectedCategory = computed(() => {
    let name = ''
    if (selectedCategory1.value.categoryName) {
      name += selectedCategory1.value.categoryName
    }
    if (selectedCategory2.value.categoryName) {
      name += ` ＞ ${selectedCategory2.value.categoryName}`
    }
    if (selectedCategory3.value.categoryName) {
      name += ` ＞ ${selectedCategory3.value.categoryName}`
    }
    return name
  })

  onMounted(() => {
    getLatestUsedList()
    if (props.defaultValue[0]) {
      selectedCategory1.value = {
        categoryName: '',
        categoryId: props.defaultValue[0] as number
      }
      selectedCategory2.value = {
        categoryName: '',
        categoryId: props.defaultValue[1] as number
      }
      selectedCategory3.value = {
        categoryName: '',
        categoryId: props.defaultValue[2] as number
      }
    }
  })

  async function getLatestUsedList() {
    const { data } = await store.dispatch('product/productCategoryLatestList')
    latestUsedList.value = data || []
  }

  async function getSearchList(query: string) {
    const { data } = await store.dispatch('product/productCategorySearch', {
      categoryName: query
    })
    searchList.value =
      data?.map((item: ProductCategoryListModel) => ({
        ...item,
        value: item.categoryId3,
        label: `${item.categoryName1}＞${item.categoryName2}＞${item.categoryName3}`
      })) || []
  }

  function handleClickTag(item: ProductCategoryListModel) {
    const { categoryId1, categoryName1, categoryName2, categoryName3, categoryId2, categoryId3 } = item
    selectedCategory1.value = {
      categoryName: categoryName1,
      categoryId: categoryId1
    }
    selectedCategory2.value = {
      categoryName: categoryName2,
      categoryId: categoryId2
    }
    selectedCategory3.value = {
      categoryName: categoryName3,
      categoryId: categoryId3
    }
  }

  async function handleSearch(query: string) {
    const queryTrim = query.trim()
    if (!queryTrim.length) {
      searchList.value = []
      return
    }
    loading.value = true
    await getSearchList(queryTrim).finally(() => {
      searchValue.value = queryTrim
      loading.value = false
    })
  }

  function renderLabel(option: ProductCategoryListModel) {
    const reg = new RegExp(`(${searchValue.value})`, 'ig')
    const list = option?.label?.split(reg)
    return list.map((item: string) =>
      h(
        'span',
        {
          style:
            item.toLocaleLowerCase() === searchValue.value.toLocaleLowerCase()
              ? {
                  color: 'rgb(90, 102, 255)'
                }
              : ''
        },
        item
      )
    )
  }

  function handleUpdateCategory1(item, type: string) {
    if (type === 'backfill') return
    selectedCategory2.value = {
      categoryName: '',
      categoryId: null
    }
    selectedCategory3.value = {
      categoryName: '',
      categoryId: null
    }
  }

  function handleUpdateCategory2(item, type: string) {
    if (type === 'backfill') return
    selectedCategory3.value = {
      categoryName: '',
      categoryId: null
    }
  }

  function handleUpdateCategory3(item, type: string) {
    selectedCategory3.value = item
  }

  function handleUpdateSelectedValue(val: number, item: ProductCategoryListModel) {
    handleClickTag(item)
    selectedValue.value = null
    searchList.value = []
  }

  function handleClose() {
    getProps.modalData.show = false
  }

  function handleConfirm() {
    const { categoryId: categoryId1, categoryName: categoryName1 } = selectedCategory1.value
    const { categoryId: categoryId2, categoryName: categoryName2 } = selectedCategory2.value
    const { categoryId: categoryId3, categoryName: categoryName3 } = selectedCategory3.value
    emits('success', [
      { ...selectedCategory1.value, id: categoryId1 },
      { ...selectedCategory2.value, id: categoryId2 },
      { ...selectedCategory3.value, id: categoryId3 }
    ])
    store.dispatch('product/productCategoryLatestAdd', {
      categoryId1,
      categoryName1,
      categoryId2,
      categoryName2,
      categoryId3,
      categoryName3
    })
    handleClose()
  }
</script>

<style scoped lang="scss">
  .container {
    height: 500px;
    display: flex;
    flex-direction: column;
  }
  .category-tag {
    cursor: pointer;
  }

  .latest-used-box {
    margin-bottom: 10px;
  }

  .content-box {
    flex: 1;
    background-color: #fafafa;
    border-radius: 4px;
    padding: 12px;
    overflow: hidden;

    > .search {
      margin: 0 200px 10px 0;
    }
  }
  .selected-box {
    margin-top: 10px;
  }

  .category-box {
    height: calc(100% - 44px);
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
  }
</style>
